package com.jjyd.crlp.aop;

import com.jjyd.crlp.model.base.ResultListModel;
import com.jjyd.crlp.model.code.CommonErrorCode;
import com.jjyd.crlp.util.check.CheckException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;


/**
 * 拦截controller的请求
 * 记录异常（暂时只有CheckException）
 */
@Aspect
@Component
@Slf4j
public class ControllerException {

    /**
     * 环绕通知：目标方法执行之前执行以下方法体的内容
     */
    @Around(value = "@within(org.springframework.web.bind.annotation.RestController)")
    public Object aroundMethod(ProceedingJoinPoint pjp) {

        try {
            Object o = pjp.proceed();
            return o;
        } catch (Throwable e) {
            return handlerException(pjp, e);
        } finally {
            //最后清除mdc
            MDC.clear();
        }
    }

    /**
     * 处理异常
     * @return 返回一个失败信息
     */
    private Object handlerException(ProceedingJoinPoint pjp, Throwable e) {
        //定义错误信息
        String msg;
        if (e instanceof CheckException) {
            //正查检测出来的异常，可以不放入错误日志
            msg = e.getMessage();
            log.info("param error, controller=[{}], e=[{}]", pjp.getSignature(), e);
        } else {
            //未知的异常，通用掉此方法
            log.error("other error, controller=[{}], e=[{}]", pjp.getSignature(), e);
            msg = "未知错误，请联系技术部";
        }
        return new ResultListModel<>(CommonErrorCode.FAILED, msg, null);
    }

}
